﻿namespace Cos.Module.Blog
{
    using System;
    using System.Collections.Generic;
    using Cos.Core.Model.Blog;
    using Cos.Core.Model.Common;
    using Cos.Core.Service;
    using Cos.Module.Blog.Data;
    using Cos.Module.Blog.Exceptions;
    using Microsoft.Practices.Unity;

    /// <summary>
    /// Blog Service
    /// </summary>
    public class BlogService : ServiceBase, IBlogService
    {
        /// <summary>
        /// blog Repository
        /// </summary>
        private readonly IBlogRepository blogRepository;

        /// <summary>
        /// Initializes a new instance of the <see cref="BlogService"/> class.
        /// </summary>
        /// <param name="blogRepository">The blog repository.</param>
        [InjectionConstructor]
        public BlogService(IBlogRepository blogRepository)
        {
            this.blogRepository = blogRepository;
        }

        /// <summary>
        /// Gets the list of tags.
        /// </summary>
        public IEnumerable<Tag> GetTags
        {
            get { return this.blogRepository.Tags; }
        }

        /// <summary>
        /// Gets the blog from blog id.
        /// </summary>
        /// <param name="blogId">blogId the id of the blog.</param>
        /// <param name="culture">The culture.</param>
        /// <returns>
        /// The blog from blog id.
        /// </returns>
        /// <exception cref="BlogNotFoundException">If the blog could not be found or converted.</exception>
        public Core.Model.Blog.Blog GetBlog(int blogId, Culture culture)
        {
            if (culture == null)
            {
                throw new BlogNotFoundException("Not such blog in the database. Culture: " + culture);
            }

            return this.blogRepository.GetBlog(blogId, culture);
        }

        /// <summary>
        /// Used to retrieve the number of articles of a blog
        /// </summary>
        /// <param name="blogId">blogId id of the blog.</param>
        /// <returns>
        /// The number of articles
        /// </returns>
        public int GetNumberOfArticles(int blogId)
        {
            return this.blogRepository.GetNumberOfArticles(blogId);
        }

        /// <summary>
        /// Gets the article by id.
        /// </summary>
        /// <param name="articleId">id of the article.</param>
        /// <returns>
        /// The article.
        /// </returns>
        /// <exception cref="ArticleNotFoundException">The article could not be found or converted</exception>
        public Article GetArticle(int articleId, Culture culture)
        {
            return this.blogRepository.GetArticle(articleId, culture);
        }

        /// <summary>
        /// Gets the articles associated to a blog.
        /// </summary>
        /// <param name="blogId">the id of the blog.</param>
        /// <param name="culture">The culture.</param>
        /// <returns>
        /// The articles
        /// </returns>
        /// <exception cref="ArticleNotFoundException">the article could not be found or converted</exception>
        public IEnumerable<Article> GetArticles(int blogId, Culture culture)
        {
            return this.GetArticles(blogId, culture, 0, -1, long.MaxValue);
        }

        /// <summary>
        /// Gets the X latest articles associated to a blog.
        /// </summary>
        /// <param name="blogId">the id of the blog.</param>
        /// <param name="culture">The culture.</param>
        /// <param name="maxResult">maximum articles to retrieve.</param>
        /// <param name="toDate">return maxResult articles until the toDate is reached.</param>
        /// <returns>
        /// The articles
        /// </returns>
        /// <exception cref="ArticleNotFoundException">the article could not be found or converted</exception>
        public IEnumerable<Article> GetArticles(int blogId, Culture culture, int maxResult, long toDate)
        {
            return this.GetArticles(blogId, culture, 0, maxResult, toDate);
        }

        /// <summary>
        /// Gets the articles associated to a blog.
        /// </summary>
        /// <param name="blogId">the id of the blog.</param>
        /// <param name="culture">The culture.</param>
        /// <param name="firstResult">tell to start at the firstResult id.</param>
        /// <param name="maxResult">maximum articles to retrieve.</param>
        /// <param name="toDate">maxResult articles until the toDate is reached.</param>
        /// <returns>
        /// The articles
        /// </returns>
        /// <exception cref="ArticleNotFoundException">the article could not be found or converted</exception>
        public IEnumerable<Article> GetArticles(int blogId, Culture culture, int firstResult, int maxResult, long toDate)
        {
            if (culture == null)
            {
                throw new ArticleNotFoundException("Not such article in the database. Culture: " + culture);
            }

            return this.blogRepository.GetArticles(blogId, culture, firstResult, maxResult, toDate);
        }

        /// <summary>
        /// Updates the article.
        /// </summary>
        /// <param name="article">the article to save.</param>
        public void UpdateArticle(Article article)
        {
            if (article == null)
            {
                throw new ArgumentNullException("article");
            }

            this.blogRepository.UpdateArticle(article);
        }

        /// <summary>
        /// Submit an article.
        /// </summary>
        /// <param name="blogId">the id of the blog.</param>
        /// <param name="culture">The culture.</param>
        /// <param name="article">the article to savee.</param>
        public void SubmitArticle(int blogId, Culture culture, Article article)
        {
            if (culture == null)
            {
                throw new ArgumentNullException("Culture");
            }
            
            if (article == null)
            {
                throw new ArgumentNullException("article");
            }

            this.blogRepository.SubmitArticle(blogId, culture, article);
        }

        /// <summary>
        /// Deletes the article.
        /// </summary>
        /// <param name="articleId">id of the article.</param>
        public void DeleteArticle(int articleId)
        {
            this.blogRepository.DeleteArticle(articleId);
        }

        /// <summary>
        /// Submits the comment.
        /// </summary>
        /// <param name="culture">The culture.</param>
        /// <param name="comment">The comment to save.</param>
        public void SubmitComment(Culture culture, Comment comment)
        {
            if (culture == null)
            {
                throw new ArgumentNullException("culture");
            }

            if (comment == null)
            {
                throw new ArgumentNullException("comment");
            }

            this.blogRepository.SubmitComment(culture, comment);
        }

        /// <summary>
        /// Deletes the comment.
        /// </summary>
        /// <param name="commentId">The comment.</param>
        public void DeleteComment(int commentId)
        {
            this.blogRepository.DeleteComment(commentId);
        }
    }
}
